import os

############################################################################################
print('\n第31部分')
'''
None    也是一个对象，有自己的类型
不是空字符串，不是0，不是False
和其他任何类型比较，返回bool布尔值都是False
'''

a = None
print(id(a), type(a))  # 140709793131720 <class 'NoneType'>
print(a is 0)
print(a is '')


############################################################################################
print('\n第30部分')
'''
python是一门面向对象的编程语言
继承、多态、封装

1、什么是面向对象？
它是一种编程范式 以对象为核心 来组织程序代码和数据
通俗来说，可以当作图纸、模板

一切都是对象  数据类型，函数（方法），包括class（也就是类） 都是对象
定义一个类，里面有属性（特征）、方法（函数）
对象 可以想象成一个具体事物，有自己的特征（属性），如长、宽、是木头还是钢铁；有自己的行为：能跑或者游泳、会不会吃饭

类 也是封装 我们可以在里面封装多个属性、多个方法

2、什么是面向过程？
简单，不需要协作的事物
过程：按照步骤，一步步执行

'''


'''
三大基础特征

封装  多行代码可以封装在函数里，使用时可以直接调用
继承  
多态  是指同一个方法被调用，由于对象不同会产生不同的行为

类有属性（特征）、方法（函数）

# 类的命名方法  遵循驼峰命名法 大驼峰
'''



class Car(object):
    def __init__(self, color):  # 初始化方法，生成实例对象会自动执行这个初始化方法
        self.color = color  # 实例对象的属性，特征    颜色

    # 方法 行为 函数
    def run(self):
        print('车跑起来了')
        print(f'这辆{self.color}颜色的车跑起来了')

    @staticmethod
    def distance(a, b):
        return a + b


car1 = Car('red')  # 类的实例化，生成一个实例对象
car1.run()
'''
静态方法 @staticmethod  挂在类的下面，但是和类无关

类.静态方法  可以调用
类的实例对象.静态方法 也可以调用
'''
Car.distance(2, 3)  # 类.静态方法
car1.distance(5, 6)  # 类的实例对象.静态方法

class MyT:
    def say(self):
        print('我是1号方法')

    def say(self):  #
        print('我是新修改的2号方法')


def say(self):  # 【重新的类的方法】，【self必须要有】
    print('我是类外的3号方法')


MyT.say = say
m = MyT()
m.say()


'''
__init__    构造函数，在生成实例对象时调用
__str__     把内存地址 转化为我们先描述的信息   便于调试和开发
__del__     析构函数，在实例对象被销毁时调用
__call__    让类的实例对象，可以像函数一样被调用
'''


class Car(object):
    def __init__(self, color):
        # 初始化方法，生成实例对象会自动执行这个初始化方法
        self.color = color  # 实例对象的属性，特征    颜色
        self.size = 240
        print('生成一个新车（实例对象）')

    def __str__(self):
        # 把内存地址 转化为我们先描述的信息   便于调试和开发
        # 如果没有重新这个方法，返回的内容是一个内存地址
        return f'车的颜色是{self.color}，大小是{self.size}'

    def __del__(self):
        # 析构函数，在实例对象被销毁时调用
        print(f'这个车（实例对象）被销毁了')
        print(self)

    def __call__(self, x):
        return x * 2


car1 = Car('red')  # 类的实例化（生成实例对象），触发__init__方法
print(car1)  # 触发__str__方法
print(car1(20))  # 输出40，实例对象加括号直接调用__call__函数
del car1  # 触发__del__方法


'''
私有属性
私有方法
property方法和调用
'''


class Mine(object):
    """
    私有属性，私有方法展示
    """
    def __init__(self, name):
        """私有属性__money"""
        self.name = name  # 共有属性，也就是实例属性
        self.__money = 2400  # 私有属性

    def set_money(self, money):
        """设置私密属性__money"""
        self.__money = money

    def get_money(self):
        """调用私有属性__money"""
        print(self.__money)

    def __Make_work(self):
        """私有方法__money"""
        print('go to work')
        print('complete')
        print('go home')

    def work(self):
        """调用私有方法__Make_work"""
        self.__Make_work()

    @property
    def my_work(self):
        """调用property方法
        可以用：实例对象.my_work
        不加括号
        """
        print('my_work')

    @property
    def my_work2(self, status):
        """调用property方法
        可以用：实例对象.my_work
        不加括号
        """
        print('my_work2:{}'.format(status))


m = Mine('Tom')
print(m.name)
m.get_money()  # 获取私有属性
m.work()  # 调用私有方法__Make_work
m.set_money(100000)  # 设置私有属性
m.get_money()  # 获取私有属性
m.my_work
m.my_work2 = 2
print(hasattr(m, '__money'))  # 检查实例对象【有没有】__money属性
print(getattr(m, 'name'))  # 【获取】实例对象__money属性
setattr(m, 'name', 'jerry')  # 【设置】实例对象__money属性
print(getattr(m, 'name'))  # 【获取】实例对象__money属性
delattr(m, 'name')  # 【删除】实例对象__money属性
print(hasattr(m, 'name'))  # 检查实例对象【有没有】__money属性
del m


'''
类的属性    类里面直接定义的变量，
类的方法    @classmethod    cls指的是类本身
静态方法    @staticmethod   和类无关，但挂在类的下面

实例对象的属性 类生成实例对象时，进行定义的变量（初始化方法__init__）
self 指的是实例对象本身
cls  指的是类本身



__new__     实例化对象时调用，返回一个对象实例
__init__    构造函数，在生成实例对象时调用
__call__    允许对象像函数一样被调用
__del__     析构函数，在对象被销毁时调用

__name__    类、函数、方法等的名称
__class__   对象或类所属的类
__module__  类定义所在的模块名称
__bases__   类的基类（父类）的元组
__doc__     类、函数的文档字符串
__dict__    类或实例的属性字典
__qualname__    类的限定名

__repr__    返回对象的官方字符串表示
__setitem__ 和 __getitem__   允许按照索引赋值和获取值
__len__     返回对象的长度
__cmp__     进行比较运算
__add__、__sub__、__mul__、__div__、__mod__、__pow__     进行算术运算

属性访问与修改
访问属性：对象.属性名
修改属性：对象.属性名 = 新值
删除属性：del 对象.属性名

注意事项
类属性可以通过类名直接访问，也可以通过实例访问，但实例属性会覆盖类属性
使用@property装饰器可以将方法变成属性调用
使用@property装饰器定义的属性，可以通过.属性名的方式访问，但不能通过赋值语句修改
    @property
    def my_work(self):
        print(123)
    调用可以用：


print(hasattr(m, '__money'))  # 检查实例对象【有没有】__money属性

setattr(m, 'name', 'jerry')  # 【设置】实例对象__money属性

print(getattr(m, 'name'))  # 【获取】实例对象__money属性

delattr(m, 'name')  # 【删除】实例对象__money属性


'''


'''
封装  多行代码可以封装在函数里，使用时可以直接调用

私有属性，私有方法
实例属性，实例方法
类的属性，类的方法

函数是 封装多行代码语句块
类   也是封装多个属性和多个方法


继承
子类继承父类的特性，如object，提高代码复用性，
原父类设计不变，子类里面添加一些新的方法，或改进原父类的方法

之前的__str__，__cal__都是这种改进父类object的


多态
是指同一个方法被调用，由于对象不同会产生不同的行为
'''


# 多态——————————————————————————————————
class Animal(object):
    """
    设置好的父类Animal
    """
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def say(self):
        print(f'这个动物是{self.name}，年龄是{self.age}')

    def run(self):
        print(f'一个{self.name}在路上跑')

    def my_type(self):
        print(self.__str__())


class Dog(Animal):
    """
    Dog继承Animal，狗类继承了动物类
    """
    def __init__(self, name, age):
        # super().__init__(self, name, age)  # 继承父类的方法一
        Animal.__init__(self, name, age)  # 继承父类的方法二
        """
        【子类不重写】初始化方法__init__，实例化的子类时候会【自动调用父类】的初始化方法__init__
        【子类重写】了初始化方法__init__，那么实例化会【调用子类】的初始化方法__init__
        """
    def run(self):
        print(f'我是{self.name}，我喜欢在公园跑')

    def say(self):
        print('汪汪')

    def my_type(self):
        print(self.__str__())


class Cat(Animal):
    def say(self):
        print('喵喵')


dog = Dog('Dog', 23)
dog.say()
dog.run()

cat = Cat('Cat', 23)
cat.say()

"""
Dog继承Animal，Cat也继承Animal，这就是多态
"""


class Hashiqi(Dog):
    """
    Hashiqi继承Dog，Dog继承Animal，这就是多重继承
    """
    def my_type(self):
        print(self.__str__())

